#include "Business.h"
#include <Windows.h>

Business::Business(QObject *parent) : QObject(parent)
{
    // 打开设备
    KSError error = KS_openDriver(customer_number_);
    if (error != KS_OK)
    {
        Universal::OutputErr(error, "KS_openDriver", "Unable to open the driver!");
        return;
    }

    // 创建共享内存
    error = KS_createSharedMemEx(&app_shared_data_handle_, "", sizeof(SharedData), KSF_NO_FLAGS);
    if (error != KS_OK)
    {
        Universal::OutputErr(error, "KS_createSharedMemEx", "Unable to create shared memory!");
        return;
    }

    // 获取共享内存句柄
    error = KS_getSharedMemEx(app_shared_data_handle_, reinterpret_cast<void **>(&app_shared_data_), KSF_NO_FLAGS);
    if (error != KS_OK)
    {
        Universal::OutputErr(error, "KS_getSharedMemEx", "Unable to map shared memory!");
        return;
    }

    KSSystemInformation system_info;
    system_info.structSize = sizeof(KSSystemInformation);
    error = KS_getSystemInformation(&system_info, KSF_NO_FLAGS);
    if (error != KS_OK)
    {
        Universal::OutputErr(error, "KS_getSystemInformation", "Unable to get system information to distinguish bitsize!");
        return;
    }

    // 设置Task处理专用CPU
    app_shared_data_->task_cpu = system_info.numberOfSharedCPUs;
}

Business::~Business()
{
    // 共享内存释放
    if (app_shared_data_handle_ != NULL)
    {
        if (const KSError error = KS_freeSharedMemEx(app_shared_data_handle_, KSF_NO_FLAGS); error != KS_OK)
        {
            Universal::OutputErr(error, "KS_freeSharedMemEx", "Unable to remove shared memory!");
        }
    }

    if (const KSError error = KS_closeDriver(); error != KS_OK)
    {
        Universal::OutputErr(error, "KS_closeDriver", "Unable to close the driver!");
    }
    Sleep(2000);
}

bool Business::Start() const
{
    if (app_shared_data_ == nullptr) { return false;}

    app_shared_data_->abort = 0;

    // 加载内核DLL
#ifdef EZ_DEBUG   // 调试模式
    KSError error = KS_loadLibraryKernel(&app_shared_data_->kernel_handle, "Kernel.dll", nullptr, nullptr, KSF_NO_FLAGS);
    if (error != KS_OK)
    {
        Universal::OutputErr(error, "KS_loadLibraryKernel", "Unable to load DLLs or problems while executing entrypoints!");
        return false;
    }
#else
    KSError error = KS_loadLibraryKernel(&app_shared_data_->kernel_handle, "Kernel.dll", nullptr, nullptr, KSF_KERNEL_EXEC);
    if (error != KS_OK)
    {
        Universal::OutputErr(error, "KS_loadLibraryKernel", "Unable to load DLLs or problems while executing entrypoints!");
        return false;
    }
#endif

    // 执行内核初始化函数
    error = KS_execKernelFunctionEx(app_shared_data_->kernel_handle, "InitFunction", app_shared_data_handle_, KS_INVALID_HANDLE, KSF_NO_FLAGS);
    if (error != KS_OK)
    {
        Universal::OutputErr(error, "KS_execKernelFunctionEx", "Unable to initialize the KernelDll DLL!");
        return false;
    }

    Universal::OutputTxt("started.");
    return true;
}

bool Business::RunStatus() const
{
    if (app_shared_data_ == nullptr || app_shared_data_->abort == 1)
    {
        return false;
    }

    return true;
}

void Business::SetRunScript(const bool run) const
{
    if (app_shared_data_ == nullptr) { return; }
    app_shared_data_->script_run_status = run;
}

bool Business::ScriptStatus() const
{
    if (app_shared_data_ == nullptr) { return false; }
    return app_shared_data_->script_run_status;
}

void Business::Stop() const
{
    if (app_shared_data_ == nullptr) { return; }

    if (app_shared_data_->kernel_handle != NULL)
    {
        KSError error = KS_execKernelFunctionEx(app_shared_data_->kernel_handle, "ExitFunction", NULL, NULL, KSF_NO_FLAGS);
        if (error != KS_OK)
        {
            Universal::OutputErr(error, "KS_execKernelFunctionEx", "Error while deallocating resources on KernelDll level!");
        }

        // 内核资源释放
        error = KS_freeKernel(app_shared_data_->kernel_handle);
        if (error != KS_OK)
        {
            Universal::OutputErr(error, "KS_freeKernel", "Unable to unload the KernelDll!");
        }
    }

    Universal::OutputTxt("stopped!");
}


